Skip to content

feat(csharp): make core ADBC and trace listeners AOT-compatible to support standalone C# drivers#4243

Open
CurtHagenlocher wants to merge 3 commits intoapache:mainfrom
CurtHagenlocher:ExportCSharp
Open

feat(csharp): make core ADBC and trace listeners AOT-compatible to support standalone C# drivers#4243
CurtHagenlocher wants to merge 3 commits intoapache:mainfrom
CurtHagenlocher:ExportCSharp

Conversation

@CurtHagenlocher
Copy link
Copy Markdown
Contributor

@CurtHagenlocher CurtHagenlocher commented Apr 19, 2026

Adds net10.0 to the target frameworks for Apache.Arrow.Adbc and the trace-listener assembly, with <IsAotCompatible>true</IsAotCompatible> enabled on that TFM.

  • Replace FileVersionInfo.GetVersionInfo(assembly.Location) with AssemblyInformationalVersionAttribute lookup; Assembly.Location is empty under single-file publish. A guarded FileVersionInfo fallback is retained for JIT via RuntimeFeature.IsDynamicCodeSupported.

  • Rewrite IArrowArrayExtensions.SerializeToJson to dispatch through Utf8JsonWriter instead of the reflection-based JsonSerializer. Every value type ParseStructArray can produce is dispatched explicitly. SqlDecimal (Decimal128) now emits as a JSON number when the declared precision is <= 15 and as a string otherwise, replacing the previous accidental {IsNull, Value, Precision, ...} shape.

  • Rewrite FileListener.ActivityProcessor to serialize via a source-generated JsonSerializerContext. A new OtelAttributesConverter preserves OpenTelemetry-compatible attribute values (string, bool, int64, double, and homogeneous arrays) as native JSON; non-OTel values fall back to invariant-culture strings so the output doesn't drift by locale.

  • CAdbcDriverExporter.AdbcDriverInit returns NotImplemented rather than InternalError for unsupported ADBC versions so the importer's 1.1.0 -> 1.0.0 fallback works.

  • Add InternalsVisibleTo for Apache.Arrow.Adbc.Testing (the actual assembly name; the existing Apache.Arrow.Adbc.Tests entry is stale).

Covered by 27 new golden-output tests for SerializeToJson, 14 new tests for OtelAttributesConverter (including invariant-culture verification under a non-English locale) and 4 new tests for the driver exporter.

  Adds net10.0 to the target frameworks for Apache.Arrow.Adbc and the
  trace-listener assembly, with <IsAotCompatible>true</IsAotCompatible>
  enabled on that TFM.

  - Replace FileVersionInfo.GetVersionInfo(assembly.Location) with
    AssemblyInformationalVersionAttribute lookup; Assembly.Location is
    empty under single-file publish. A guarded FileVersionInfo fallback
    is retained for JIT via RuntimeFeature.IsDynamicCodeSupported.

  - Rewrite IArrowArrayExtensions.SerializeToJson to dispatch through
    Utf8JsonWriter instead of the reflection-based JsonSerializer. Every
    value type ParseStructArray can produce is dispatched explicitly.
    SqlDecimal (Decimal128) now emits as a JSON number when the declared
    precision is <= 15 and as a string otherwise, replacing the previous
    accidental {IsNull, Value, Precision, ...} shape.

  - Rewrite FileListener.ActivityProcessor to serialize via a source-
    generated JsonSerializerContext. A new OtelAttributesConverter
    preserves OpenTelemetry-compatible attribute values (string, bool,
    int64, double, and homogeneous arrays) as native JSON; non-OTel
    values fall back to invariant-culture strings so the output doesn't
    drift by locale.

  - CAdbcDriverExporter.AdbcDriverInit returns NotImplemented rather
    than InternalError for unsupported ADBC versions so the importer's
    1.1.0 -> 1.0.0 fallback works.

  - Add InternalsVisibleTo for Apache.Arrow.Adbc.Testing (the actual
    assembly name; the existing Apache.Arrow.Adbc.Tests entry is stale).

  Covered by 27 new golden-output tests for SerializeToJson and 14 new
  tests for OtelAttributesConverter (including invariant-culture
  verification under a non-English locale).
@CurtHagenlocher CurtHagenlocher requested a review from Copilot April 19, 2026 03:42
@CurtHagenlocher CurtHagenlocher changed the title feat(csharp): make core ADBC and trace listeners AOT-compatible feat(csharp): make core ADBC and trace listeners AOT-compatible Apr 19, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the C# ADBC core and telemetry trace listener code to be AOT-friendly (including single-file publish), primarily by avoiding reflection-based JSON serialization and Assembly.Location-dependent version lookups, and by adding a new TFM intended for AOT scenarios.

Changes:

  • Add net10.0 target framework (with IsAotCompatible=true) for Apache.Arrow.Adbc and the telemetry listeners assembly.
  • Replace reflection-based JSON serialization with Utf8JsonWriter (struct-to-JSON) and source-generated System.Text.Json context (trace file listener), including new OTel attribute converters.
  • Adjust ADBC driver init status code for unsupported versions and update InternalsVisibleTo for the correct testing assembly.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
csharp/src/Apache.Arrow.Adbc/Apache.Arrow.Adbc.csproj Adds net10.0 TFM and marks it AOT-compatible.
csharp/src/Telemetry/Traces/Listeners/Apache.Arrow.Adbc.Telemetry.Traces.Listeners.csproj Adds net10.0 TFM and marks it AOT-compatible.
csharp/src/Apache.Arrow.Adbc/Tracing/ActivityTrace.cs Switches assembly version retrieval to informational attribute + guarded file version fallback.
csharp/src/Apache.Arrow.Adbc/Extensions/IArrowArrayExtensions.cs Rewrites struct-to-JSON serialization to use Utf8JsonWriter with explicit type dispatch.
csharp/test/Apache.Arrow.Adbc.Tests/SerializeStructToJsonTests.cs Adds golden-output tests for the new struct-to-JSON serialization output.
csharp/src/Telemetry/Traces/Listeners/FileListener/ActivityProcessor.cs Uses source-generated JSON serialization for activities on NET6_0_OR_GREATER.
csharp/src/Telemetry/Traces/Listeners/FileListener/TraceJsonContext.cs Introduces JsonSerializerContext for source-generated trace JSON.
csharp/src/Telemetry/Traces/Listeners/FileListener/SerializableActivity.cs Adds JSON converters for activity tag payloads to preserve OTel-compatible shapes.
csharp/src/Telemetry/Traces/Listeners/FileListener/OtelAttributesConverter.cs Implements converters + writer to emit OTel-native JSON scalars/arrays and invariant-string fallbacks.
csharp/test/Telemetry/Traces/Listeners/FileListener/OtelAttributesConverterTests.cs Adds tests for OTel attribute JSON emission and locale-invariant fallbacks.
csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs Returns NotImplemented for unsupported ADBC versions to enable importer fallback behavior.
csharp/src/Apache.Arrow.Adbc/Properties/AssemblyInfo.cs Adds InternalsVisibleTo for Apache.Arrow.Adbc.Testing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread csharp/src/Apache.Arrow.Adbc/Tracing/ActivityTrace.cs
Comment thread csharp/src/Telemetry/Traces/Listeners/FileListener/OtelAttributesConverter.cs Outdated
Comment thread csharp/src/Apache.Arrow.Adbc/Apache.Arrow.Adbc.csproj
name: "C# NativeAOT smoke test (windows-2022)"
runs-on: windows-2022
# if: ${{ !contains(github.event.pull_request.title, 'WIP') }}
if: false
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disabled for now

}

[Fact]
public void Decimal128_NarrowPrecision_AsNumber()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidhcoe, decimal128 values were previously being JSON-converted to something like {"IsNull":false,"Value":123.45,"IsPositive":true,"Precision":10,"Scale":2,"Data":[12345,0,0,0],"BinData":"OTAAAAAAAAAAAAAAAAAAAA=="} because that's how JsonSerializer translates SqlDecimal. I've taken the liberty of making this breaking change in the output because I can't imagine that anyone was making use of that. Feel free to raise an objection.

# link.exe step can find link.exe/lib.exe and the Windows SDK.
# The existing workflow only uses first-party actions, so flag
# this for review before enabling.
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be fairly widely used and hasn't been changed in a while. (This was a Claude suggestion.)

@CurtHagenlocher CurtHagenlocher changed the title feat(csharp): make core ADBC and trace listeners AOT-compatible feat(csharp): make core ADBC and trace listeners AOT-compatible to support standalone C# drivers Apr 19, 2026
public string? ParentSpanId { get; set; }
public string? IdFormat { get; set; }

[JsonConverter(typeof(OtelAttributesDictionaryConverter))]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants